home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / sound / astrocde.c < prev    next >
C/C++ Source or Header  |  2000-05-20  |  8KB  |  329 lines

  1. /***********************************************************
  2.  
  3.      Astrocade custom 'IO' chip sound chip driver
  4.      Frank Palazzolo
  5.  
  6.      Portions copied from the Pokey emulator by Ron Fries
  7.  
  8.      First Release:
  9.          09/20/98
  10.  
  11.      Issues:
  12.          Noise generators need work
  13.         Can do lots of speed optimizations
  14.  
  15. ***********************************************************/
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <math.h>
  20.  
  21. #include "driver.h"
  22. #include "cpu/z80/z80.h"
  23.  
  24.  
  25. static const struct astrocade_interface *intf;
  26.  
  27. static int emulation_rate;
  28. static int div_by_N_factor;
  29. static int buffer_len;
  30.  
  31. static INT16 *astrocade_buffer[MAX_ASTROCADE_CHIPS];
  32.  
  33. static int sample_pos[MAX_ASTROCADE_CHIPS];
  34.  
  35. static int current_count_A[MAX_ASTROCADE_CHIPS];
  36. static int current_count_B[MAX_ASTROCADE_CHIPS];
  37. static int current_count_C[MAX_ASTROCADE_CHIPS];
  38. static int current_count_V[MAX_ASTROCADE_CHIPS];
  39. static int current_count_N[MAX_ASTROCADE_CHIPS];
  40.  
  41. static int current_state_A[MAX_ASTROCADE_CHIPS];
  42. static int current_state_B[MAX_ASTROCADE_CHIPS];
  43. static int current_state_C[MAX_ASTROCADE_CHIPS];
  44. static int current_state_V[MAX_ASTROCADE_CHIPS];
  45.  
  46. static int current_size_A[MAX_ASTROCADE_CHIPS];
  47. static int current_size_B[MAX_ASTROCADE_CHIPS];
  48. static int current_size_C[MAX_ASTROCADE_CHIPS];
  49. static int current_size_V[MAX_ASTROCADE_CHIPS];
  50. static int current_size_N[MAX_ASTROCADE_CHIPS];
  51.  
  52. static int channel;
  53.  
  54. /* Registers */
  55.  
  56. static int master_osc[MAX_ASTROCADE_CHIPS];
  57. static int freq_A[MAX_ASTROCADE_CHIPS];
  58. static int freq_B[MAX_ASTROCADE_CHIPS];
  59. static int freq_C[MAX_ASTROCADE_CHIPS];
  60. static int vol_A[MAX_ASTROCADE_CHIPS];
  61. static int vol_B[MAX_ASTROCADE_CHIPS];
  62. static int vol_C[MAX_ASTROCADE_CHIPS];
  63. static int vibrato[MAX_ASTROCADE_CHIPS];
  64. static int vibrato_speed[MAX_ASTROCADE_CHIPS];
  65. static int mux[MAX_ASTROCADE_CHIPS];
  66. static int noise_am[MAX_ASTROCADE_CHIPS];
  67. static int vol_noise4[MAX_ASTROCADE_CHIPS];
  68. static int vol_noise8[MAX_ASTROCADE_CHIPS];
  69.  
  70. static int randbyte = 0;
  71. static int randbit = 1;
  72.  
  73. static void astrocade_update(int num, int newpos)
  74. {
  75.     INT16 *buffer = astrocade_buffer[num];
  76.  
  77.     int pos = sample_pos[num];
  78.     int i, data, data16, noise_plus_osc, vib_plus_osc;
  79.  
  80.     for(i=pos; i<newpos; i++)
  81.     {
  82.         if (current_count_N[i] == 0)
  83.         {
  84.             randbyte = rand() & 0xff;
  85.         }
  86.  
  87.         current_size_V[num] = 32768*vibrato_speed[num]/div_by_N_factor;
  88.  
  89.         if (!mux[num])
  90.         {
  91.             if (current_state_V[num] == -1)
  92.                 vib_plus_osc = (master_osc[num]-vibrato[num])&0xff;
  93.             else
  94.                 vib_plus_osc = master_osc[num];
  95.             current_size_A[num] = vib_plus_osc*freq_A[num]/div_by_N_factor;
  96.             current_size_B[num] = vib_plus_osc*freq_B[num]/div_by_N_factor;
  97.             current_size_C[num] = vib_plus_osc*freq_C[num]/div_by_N_factor;
  98.         }
  99.         else
  100.         {
  101.             noise_plus_osc = ((master_osc[num]-(vol_noise8[num]&randbyte)))&0xff;
  102.             current_size_A[num] = noise_plus_osc*freq_A[num]/div_by_N_factor;
  103.             current_size_B[num] = noise_plus_osc*freq_B[num]/div_by_N_factor;
  104.             current_size_C[num] = noise_plus_osc*freq_C[num]/div_by_N_factor;
  105.             current_size_N[num] = 2*noise_plus_osc/div_by_N_factor;
  106.         }
  107.  
  108.         data = (current_state_A[num]*vol_A[num] +
  109.                 current_state_B[num]*vol_B[num] +
  110.                 current_state_C[num]*vol_C[num]);
  111.  
  112.         if (noise_am[num])
  113.         {
  114.             randbit = rand() & 1;
  115.             data = data + randbit*vol_noise4[num];
  116.         }
  117.  
  118.         data16 = data<<8;
  119.         buffer[pos++] = data16;
  120.  
  121.         if (current_count_A[num] >= current_size_A[num])
  122.         {
  123.             current_state_A[num] = -current_state_A[num];
  124.             current_count_A[num] = 0;
  125.         }
  126.         else
  127.             current_count_A[num]++;
  128.  
  129.         if (current_count_B[num] >= current_size_B[num])
  130.         {
  131.             current_state_B[num] = -current_state_B[num];
  132.             current_count_B[num] = 0;
  133.         }
  134.         else
  135.             current_count_B[num]++;
  136.  
  137.         if (current_count_C[num] >= current_size_C[num])
  138.         {
  139.             current_state_C[num] = -current_state_C[num];
  140.             current_count_C[num] = 0;
  141.         }
  142.         else
  143.             current_count_C[num]++;
  144.  
  145.         if (current_count_V[num] >= current_size_V[num])
  146.         {
  147.             current_state_V[num] = -current_state_V[num];
  148.             current_count_V[num] = 0;
  149.         }
  150.         else
  151.             current_count_V[num]++;
  152.  
  153.         if (current_count_N[num] >= current_size_N[num])
  154.         {
  155.             current_count_N[num] = 0;
  156.         }
  157.         else
  158.             current_count_N[num]++;
  159.     }
  160.     sample_pos[num]    = pos;
  161. }
  162.  
  163. int astrocade_sh_start(const struct MachineSound *msound)
  164. {
  165.     int i;
  166.  
  167.     intf = msound->sound_interface;
  168.  
  169.     if (Machine->sample_rate == 0)
  170.     {
  171.         return 0;
  172.     }
  173.  
  174.     buffer_len = Machine->sample_rate / Machine->drv->frames_per_second;
  175.  
  176.     emulation_rate = buffer_len * Machine->drv->frames_per_second;
  177.     div_by_N_factor = intf->baseclock/emulation_rate;
  178.  
  179.     channel = mixer_allocate_channels(intf->num,intf->volume);
  180.     /* reserve buffer */
  181.     for (i = 0;i < intf->num;i++)
  182.     {
  183.         if ((astrocade_buffer[i] = malloc(sizeof(INT16)*buffer_len)) == 0)
  184.         {
  185.             while (--i >= 0) free(astrocade_buffer[i]);
  186.             return 1;
  187.         }
  188.         /* reset state */
  189.         sample_pos[i] = 0;
  190.         current_count_A[i] = 0;
  191.         current_count_B[i] = 0;
  192.         current_count_C[i] = 0;
  193.         current_count_V[i] = 0;
  194.         current_count_N[i] = 0;
  195.         current_state_A[i] = 1;
  196.         current_state_B[i] = 1;
  197.         current_state_C[i] = 1;
  198.         current_state_V[i] = 1;
  199.     }
  200.  
  201.     return 0;
  202. }
  203.  
  204. void astrocade_sh_stop(void)
  205. {
  206.     int i;
  207.  
  208.     for (i = 0;i < intf->num;i++){
  209.         free(astrocade_buffer[i]);
  210.     }
  211. }
  212.  
  213. void astrocade_sound_w(int num, int offset, int data)
  214. {
  215.     int i, bvalue, temp_vib;
  216.  
  217.     /* update */
  218.     astrocade_update(num,sound_scalebufferpos(buffer_len));
  219.  
  220.     switch(offset)
  221.     {
  222.         case 0:  /* Master Oscillator */
  223. #ifdef VERBOSE
  224.             logerror("Master Osc Write: %02x\n",data);
  225. #endif
  226.             master_osc[num] = data+1;
  227.         break;
  228.  
  229.         case 1:  /* Tone A Frequency */
  230. #ifdef VERBOSE
  231.             logerror("Tone A Write:        %02x\n",data);
  232. #endif
  233.             freq_A[num] = data+1;
  234.         break;
  235.  
  236.         case 2:  /* Tone B Frequency */
  237. #ifdef VERBOSE
  238.             logerror("Tone B Write:           %02x\n",data);
  239. #endif
  240.             freq_B[num] = data+1;
  241.         break;
  242.  
  243.         case 3:  /* Tone C Frequency */
  244. #ifdef VERBOSE
  245.             logerror("Tone C Write:              %02x\n",data);
  246. #endif
  247.             freq_C[num] = data+1;
  248.         break;
  249.  
  250.         case 4:  /* Vibrato Register */
  251. #ifdef VERBOSE
  252.             logerror("Vibrato Depth:                %02x\n",data&0x3f);
  253.             logerror("Vibrato Speed:                %02x\n",data>>6);
  254. #endif
  255.             vibrato[num] = data & 0x3f;
  256.  
  257.             temp_vib = (data>>6) & 0x03;
  258.             vibrato_speed[num] = 1;
  259.             for(i=0;i<temp_vib;i++)
  260.                 vibrato_speed[num] <<= 1;
  261.  
  262.         break;
  263.  
  264.         case 5:  /* Tone C Volume, Noise Modulation Control */
  265.             vol_C[num] = data & 0x0f;
  266.             mux[num] = (data>>4) & 0x01;
  267.             noise_am[num] = (data>>5) & 0x01;
  268. #ifdef VERBOSE
  269.             logerror("Tone C Vol:                      %02x\n",vol_C[num]);
  270.             logerror("Mux Source:                      %02x\n",mux[num]);
  271.             logerror("Noise Am:                        %02x\n",noise_am[num]);
  272. #endif
  273.         break;
  274.  
  275.         case 6:  /* Tone A & B Volume */
  276.             vol_B[num] = (data>>4) & 0x0f;
  277.             vol_A[num] = data & 0x0f;
  278. #ifdef VERBOSE
  279.             logerror("Tone A Vol:                         %02x\n",vol_A[num]);
  280.             logerror("Tone B Vol:                         %02x\n",vol_B[num]);
  281. #endif
  282.         break;
  283.  
  284.         case 7:  /* Noise Volume Register */
  285.             vol_noise8[num] = data;
  286.             vol_noise4[num] = (data>>4) & 0x0f;
  287. #ifdef VERBOSE
  288.             logerror("Noise Vol:                             %02x\n",vol_noise8[num]);
  289.             logerror("Noise Vol (4):                         %02x\n",vol_noise4[num]);
  290. #endif
  291.         break;
  292.  
  293.         case 8:  /* Sound Block Transfer */
  294.  
  295.             bvalue = (cpu_get_reg(Z80_BC) >> 8) & 0x0F;
  296.  
  297.             astrocade_sound_w(num, bvalue, data);
  298.  
  299.         break;
  300.     }
  301. }
  302.  
  303. WRITE_HANDLER( astrocade_sound1_w )
  304. {
  305.     astrocade_sound_w(0, offset, data);
  306. }
  307.  
  308. WRITE_HANDLER( astrocade_sound2_w )
  309. {
  310.     astrocade_sound_w(1, offset, data);
  311. }
  312.  
  313.  
  314. void astrocade_sh_update(void)
  315. {
  316.     int num;
  317.  
  318.     if (Machine->sample_rate == 0 ) return;
  319.  
  320.     for (num = 0;num < intf->num;num++)
  321.     {
  322.         astrocade_update(num, buffer_len);
  323.         /* reset position , step , count */
  324.         sample_pos[num] = 0;
  325.         /* play sound */
  326.         mixer_play_streamed_sample_16(channel+num,astrocade_buffer[num],2*buffer_len,emulation_rate);
  327.     }
  328. }
  329.